{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Poisoning using Clean Label Backdoor Attacks in ART"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2022-10-19 12:20:35.099963: I tensorflow/core/util/util.cc:169] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
      "2022-10-19 12:20:35.103590: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n",
      "2022-10-19 12:20:35.103604: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n"
     ]
    }
   ],
   "source": [
    "from __future__ import absolute_import, division, print_function, unicode_literals\n",
    "\n",
    "import os, sys\n",
    "from os.path import abspath\n",
    "\n",
    "module_path = os.path.abspath(os.path.join('..'))\n",
    "if module_path not in sys.path:\n",
    "    sys.path.append(module_path)\n",
    "\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "import tensorflow as tf\n",
    "tf.compat.v1.disable_eager_execution()\n",
    "tf.get_logger().setLevel('ERROR')\n",
    "\n",
    "import tensorflow.keras.backend as k\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import Dense, Flatten, Conv2D, MaxPooling2D, Activation, Dropout\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "from art.estimators.classification import KerasClassifier\n",
    "from art.attacks.poisoning import PoisoningAttackBackdoor, PoisoningAttackCleanLabelBackdoor\n",
    "from art.attacks.poisoning.perturbations import add_pattern_bd\n",
    "from art.utils import load_mnist, preprocess, to_categorical\n",
    "from art.defences.trainer import AdversarialTrainerMadryPGD"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In a [previous notebook](https://github.com/Trusted-AI/adversarial-robustness-toolbox/blob/main/notebooks/poisoning_dataset_mnist.ipynb) we discuss the threat of backdoor attacks on neural networks. We've also shown examples of [clean-label attacks](https://github.com/Trusted-AI/adversarial-robustness-toolbox/blob/main/notebooks/poisoning_attack_feature_collision.ipynb) that don't rely on changing the target label for their attack to succeed.\n",
    "\n",
    "In this notebook, we will run a new type of backdoor attack that operates under clean-label constraints, aptly named, Clean Label Backdoor Attacks. This method was proposed by [Turner et. al. 2018](https://people.csail.mit.edu/madry/lab/cleanlabel.pdf). "
   ]
  },
  {
   "attachments": {
    "image.png": {
     "image/png": "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"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The classification problem: Automatically detect numbers written in a check\n",
    "![image.png](attachment:image.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "(x_raw, y_raw), (x_raw_test, y_raw_test), min_, max_ = load_mnist(raw=True)\n",
    "\n",
    "# Random Selection:\n",
    "n_train = np.shape(x_raw)[0]\n",
    "num_selection = 10000\n",
    "random_selection_indices = np.random.choice(n_train, num_selection)\n",
    "x_raw = x_raw[random_selection_indices]\n",
    "y_raw = y_raw[random_selection_indices]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Adversary's goal: make some easy money \n",
    "\n",
    "The goal of the adversary is add a backdoor at test time, and turn any digit to a 9. Unlike other backdoor poisoning methods, it will only poison a small percentage of points **in the target class**.\n",
    "\n",
    "This poisoning method is effective because before the trigger is added, a PGD perturbation is added to the image based on a classifier the attacker trains separately. This makes the image difficult for the neural net to interpret, leaving only the backdoor trigger to use for classification."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<img src=\"../utils/data/images/zero_to_nine.png\" width=400>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import HTML\n",
    "HTML('<img src=\"../utils/data/images/zero_to_nine.png\" width=400>')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Poison training data\n",
    "percent_poison = .33\n",
    "x_train, y_train = preprocess(x_raw, y_raw)\n",
    "x_train = np.expand_dims(x_train, axis=3)\n",
    "\n",
    "x_test, y_test = preprocess(x_raw_test, y_raw_test)\n",
    "x_test = np.expand_dims(x_test, axis=3)\n",
    "\n",
    "# Shuffle training data\n",
    "n_train = np.shape(y_train)[0]\n",
    "shuffled_indices = np.arange(n_train)\n",
    "np.random.shuffle(shuffled_indices)\n",
    "x_train = x_train[shuffled_indices]\n",
    "y_train = y_train[shuffled_indices]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Victim bank trains a neural network"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create Keras convolutional neural network - basic architecture from Keras examples\n",
    "# Source here: https://github.com/keras-team/keras/blob/master/examples/mnist_cnn.py\n",
    "def create_model():    \n",
    "    model = Sequential()\n",
    "    model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=x_train.shape[1:]))\n",
    "    model.add(Conv2D(64, (3, 3), activation='relu'))\n",
    "    model.add(MaxPooling2D(pool_size=(2, 2)))\n",
    "    model.add(Dropout(0.25))\n",
    "    model.add(Flatten())\n",
    "    model.add(Dense(128, activation='relu'))\n",
    "    model.add(Dropout(0.5))\n",
    "    model.add(Dense(10, activation='softmax'))\n",
    "\n",
    "    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])\n",
    "    return model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Choose backdoor pattern"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7ff253598df0>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "backdoor = PoisoningAttackBackdoor(add_pattern_bd)\n",
    "example_target = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1])\n",
    "pdata, plabels = backdoor.poison(x_test, y=example_target)\n",
    "\n",
    "plt.imshow(pdata[0].squeeze())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Chose backdoor target labels for training"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Poison some percentage of all non-nines to nines\n",
    "targets = to_categorical([9], 10)[0] "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Train Proxy Classifier\n",
    "To create the poison samples, the attacker first runs PGD on a trained classifier. We would like this perturbation to be transferable and universal to other model architectures. To that end, our adversary conducts adversarial training so that perturbations are created against a robust model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2022-10-19 12:20:38.200705: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "2022-10-19 12:20:38.200729: W tensorflow/stream_executor/cuda/cuda_driver.cc:269] failed call to cuInit: UNKNOWN ERROR (303)\n",
      "2022-10-19 12:20:38.200741: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (li-3108ed4c-35b7-11b2-a85c-e77998e87f95.ibm.com): /proc/driver/nvidia/version does not exist\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a8120147086a481085626cff9c332237",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Precompute adv samples:   0%|          | 0/1 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a2b7aa4f171a43668c32b4d866713d4f",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Adversarial training epochs:   0%|          | 0/10 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2022-10-19 12:20:38.532163: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 AVX512F AVX512_VNNI FMA\n",
      "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
      "2022-10-19 12:20:38.548499: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:354] MLIR V1 optimization pass is not enabled\n"
     ]
    }
   ],
   "source": [
    "model = KerasClassifier(create_model())\n",
    "proxy = AdversarialTrainerMadryPGD(KerasClassifier(create_model()), nb_epochs=10, eps=0.15, eps_step=0.001)\n",
    "proxy.fit(x_train, y_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Run Attack"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "1bd2171098d34a12a45d7e1717e097e6",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Random Initializations:   0%|          | 0/1 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Iterations:   0%|          | 0/200 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a9f547f6e9c7405f9a202ba1badeeba6",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Random Initializations:   0%|          | 0/1 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Iterations:   0%|          | 0/200 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "98b565ef8e464747972f336b54429e97",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Random Initializations:   0%|          | 0/1 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Iterations:   0%|          | 0/200 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "d8101cb1fe8a4961ad8d8ba09579ad0f",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Random Initializations:   0%|          | 0/1 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Iterations:   0%|          | 0/200 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "c71903f0d02e473b8e53fe891231679b",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Random Initializations:   0%|          | 0/1 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Iterations:   0%|          | 0/200 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "566addbabefa47e8b5db7c5a4b7ddb70",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Random Initializations:   0%|          | 0/1 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Iterations:   0%|          | 0/200 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "65bff40f55d5472fb23e3266e6213636",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Random Initializations:   0%|          | 0/1 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Iterations:   0%|          | 0/200 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "18e76477d838410e8c6b7408a0221f7e",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Random Initializations:   0%|          | 0/1 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Iterations:   0%|          | 0/200 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "0af05a289ca7487ca7c8e8ab71c55b30",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Random Initializations:   0%|          | 0/1 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Iterations:   0%|          | 0/200 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "cf6264f597fc4c4da830a95ce769d16a",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Random Initializations:   0%|          | 0/1 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Iterations:   0%|          | 0/200 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "8f9abeb03927419792df35abbdeccba8",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Random Initializations:   0%|          | 0/1 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "PGD - Iterations:   0%|          | 0/200 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "attack = PoisoningAttackCleanLabelBackdoor(backdoor=backdoor, proxy_classifier=proxy.get_classifier(),\n",
    "                                           target=targets, pp_poison=percent_poison, norm=2, eps=5,\n",
    "                                           eps_step=0.1, max_iter=200)\n",
    "pdata, plabels = attack.poison(x_train, y_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Get modified data used to train the classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "988\n",
      "Label: 9\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPsAAAD4CAYAAAAq5pAIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAAANRUlEQVR4nO3df4wc9XnH8c8H4x/BDsWOU3M1Lj9SN61FFJNenEpBES0qIq4aE7VC8R/EVd0ef8QSUVFU6lYKatXKTUNQmiLKUSwMoUSJAsEJtInrRkUpqeuDuv6BAYNjC7vGl9QoGBQb2/f0jxtHF7iZPe/O7qz9vF/SaXfn2bl5NL6PZ3a+u/t1RAjAue+8phsA0BuEHUiCsANJEHYgCcIOJHF+Lzc2wzNjlmb3cpNAKsf0ht6M456s1lHYbV8v6YuSpkn6x4hYV/X8WZqtD/naTjYJoMKW2Fxaa/s03vY0SXdJ+qikJZJW2l7S7u8D0F2dvGZfJunFiNgbEW9K+oqkFfW0BaBunYR9oaSXJzw+UCz7GbaHbI/YHjmh4x1sDkAnun41PiKGI2IwIgana2a3NwegRCdhPyhp0YTHlxTLAPShTsK+VdJi25fbniHpE5I21tMWgLq1PfQWESdtr5H0bY0Pva2PiF21dQagVh2Ns0fEE5KeqKkXAF3E22WBJAg7kARhB5Ig7EAShB1IgrADSRB2IAnCDiRB2IEkCDuQBGEHkiDsQBKEHUiCsANJEHYgCcIOJEHYgSQIO5AEYQeSIOxAEoQdSIKwA0kQdiAJwg4kQdiBJAg7kARhB5Ig7EAShB1IgrADSXQ0ZbPtfZKOSjol6WREDNbRFID6dRT2wm9ExI9q+D0AuojTeCCJTsMekr5j+2nbQ5M9wfaQ7RHbIyd0vMPNAWhXp6fxV0fEQds/L2mT7eci4smJT4iIYUnDknSh50WH2wPQpo6O7BFxsLgdlfSopGV1NAWgfm2H3fZs2+88fV/SdZJ21tUYgHp1chq/QNKjtk//nn+KiH+ppSucEZ9f/s/4/N99oHLdXR/7+8r6BefNqKzf9+OLK+uPLP9Qae3kD/ZXrot6tR32iNgr6f019gKgixh6A5Ig7EAShB1IgrADSRB2IIk6PgiDhu35fPmHDV9YcVfluu/7j9WV9Z/75pzK+if/9FuV9T1/fVFp7fKVDL31Ekd2IAnCDiRB2IEkCDuQBGEHkiDsQBKEHUiCcfazwMnf/LXK+pbfvaO0NvzjX6lc97KbXqisx/HqrxJ7/LHLK+tXfut/S2tvVK6JunFkB5Ig7EAShB1IgrADSRB2IAnCDiRB2IEkGGc/C+z7g7HK+t6T5V/3/LXPXF+57szjW9vq6bRTr71WWT/yNx8srf3fZxZXrvsLf/tUWz1hchzZgSQIO5AEYQeSIOxAEoQdSIKwA0kQdiAJxtnPAn/1wW9U1ofuvKW0tuDxZseqL177UmntLwb+rXLddQ9cV1k/dXi0rZ6yanlkt73e9qjtnROWzbO9yfae4nZud9sE0KmpnMbfL+mtb8O6TdLmiFgsaXPxGEAfaxn2iHhS0pG3LF4haUNxf4OkG+ptC0Dd2n3NviAiDhX3X5G0oOyJtockDUnSLF3Q5uYAdKrjq/EREZKioj4cEYMRMThdMzvdHIA2tRv2w7YHJKm45bIo0OfaDftGSauK+6skPVZPOwC6peVrdtsPS7pG0nzbByR9VtI6SV+1vVrSfkk3drPJc920X6r+7vUlM/+zsr7wmwdLayfb6qg3Xj7xrso64+j1ahn2iFhZUrq25l4AdBFvlwWSIOxAEoQdSIKwA0kQdiAJPuLaB/b84cWV9V+dPr1HneBcxpEdSIKwA0kQdiAJwg4kQdiBJAg7kARhB5JgnL0PnLqgekrmfuaZ1d8+9N45h0trW1+v/mhvf39A9+zDkR1IgrADSRB2IAnCDiRB2IEkCDuQBGEHkmCcvQ/MGp3W0fpv/uK80tp5P9jf0e9uJd7/y5X1P59/f2ntyvVrKte9TN9vpyWU4MgOJEHYgSQIO5AEYQeSIOxAEoQdSIKwA0kwzt4HLt14pLJ+aOgnlfWXfm9GaW3xv7fV0pS9dEv7f0IDT/F59V5qeWS3vd72qO2dE5bdbvug7W3Fz/LutgmgU1M5jb9f0vWTLL8zIpYWP0/U2xaAurUMe0Q8Kan6PBNA3+vkAt0a29uL0/y5ZU+yPWR7xPbICR3vYHMAOtFu2O+W9B5JSyUdknRH2RMjYjgiBiNicLqqv5wQQPe0FfaIOBwRpyJiTNK9kpbV2xaAurUVdtsDEx5+XNLOsucC6A8tB0ltPyzpGknzbR+Q9FlJ19heKikk7ZN0c/daPPeNbX+usn7DttWV9Qd/++7S2l8+sKpy3di6o7KuZe+rLD9/zX3V68st6uiVlmGPiJWTLG71Lwygz/B2WSAJwg4kQdiBJAg7kARhB5LgI65ngQvvubCyftFd5W9D/sh9/1W57sNfvray/qWb/6GyPqaorKN/cGQHkiDsQBKEHUiCsANJEHYgCcIOJEHYgSQYZz8LzHx8a2X9k5f8cWlt7a0PVa77z2s+V1k/Mlb9J/Lq2KnK+rEoH4d/x8tHK9cdq6ziTHFkB5Ig7EAShB1IgrADSRB2IAnCDiRB2IEkGGc/B8y/5/ulteF7rqhc996rfqeyPm301cr6qQervyr6ziu+VlrzMaYD6yWO7EAShB1IgrADSRB2IAnCDiRB2IEkCDuQBOPsycV/76qsn2yxvrWwsn7ReeWfSh+7aHaL3446tTyy215k+7u2n7W9y/YtxfJ5tjfZ3lPczu1+uwDaNZXT+JOSbo2IJZJ+XdKnbC+RdJukzRGxWNLm4jGAPtUy7BFxKCKeKe4flbRb0kJJKyRtKJ62QdINXeoRQA3O6DW77cskXSVpi6QFEXGoKL0iaUHJOkOShiRpli5ou1EAnZny1XjbcyR9XdKnI+K1ibWICGnyGf4iYjgiBiNicLpmdtQsgPZNKey2p2s86A9FxCPF4sO2B4r6gKTR7rQIoA4tT+NtW9J9knZHxBcmlDZKWiVpXXH7WFc6xFlt/rR3lNaOvbu8JonzwJpN5TX7hyXdJGmH7W3FsrUaD/lXba+WtF/SjV3pEEAtWoY9Ir4nqewbCq6ttx0A3cLbZYEkCDuQBGEHkiDsQBKEHUiCj7iiI88/V/0RV723N32gNY7sQBKEHUiCsANJEHYgCcIOJEHYgSQIO5AE4+zoyJy9/AmdLTiyA0kQdiAJwg4kQdiBJAg7kARhB5Ig7EASDJKiIxdv/Unb674xUP3nx/fG14sjO5AEYQeSIOxAEoQdSIKwA0kQdiAJwg4kMZX52RdJekDSAkkhaTgivmj7dkl/JOmHxVPXRsQT3WoU/en8Lbsr6196dXFp7eilZZMDj5vXVkcoM5U31ZyUdGtEPGP7nZKetr2pqN0ZEZ/vXnsA6jKV+dkPSTpU3D9qe7ekFtOAAOg3Z/Sa3fZlkq6StKVYtMb2dtvrbc8tWWfI9ojtkRM63lm3ANo25bDbniPp65I+HRGvSbpb0nskLdX4kf+OydaLiOGIGIyIwem82xlozJTCbnu6xoP+UEQ8IkkRcTgiTkXEmKR7JS3rXpsAOtUy7LYt6T5JuyPiCxOWD0x42scl7ay/PQB1mcrV+A9LuknSDtvbimVrJa20vVTjw3H7JN3chf7Q58aOHausf/vKC0trl+qputtBhalcjf+epMkGRBlTB84ivIMOSIKwA0kQdiAJwg4kQdiBJAg7kARhB5Ig7EAShB1IgrADSRB2IAnCDiRB2IEkCDuQhCOidxuzfyhp/4RF8yX9qGcNnJl+7a1f+5LorV119nZpRLx7skJPw/62jdsjETHYWAMV+rW3fu1Lord29ao3TuOBJAg7kETTYR9uePtV+rW3fu1Lord29aS3Rl+zA+idpo/sAHqEsANJNBJ229fbft72i7Zva6KHMrb32d5he5vtkYZ7WW971PbOCcvm2d5ke09xO+kcew31drvtg8W+22Z7eUO9LbL9XdvP2t5l+5ZieaP7rqKvnuy3nr9mtz1N0guSfkvSAUlbJa2MiGd72kgJ2/skDUZE42/AsP0RSa9LeiAiriyWfU7SkYhYV/xHOTci/qRPertd0utNT+NdzFY0MHGacUk3SPp9NbjvKvq6UT3Yb00c2ZdJejEi9kbEm5K+ImlFA330vYh4UtKRtyxeIWlDcX+Dxv9Yeq6kt74QEYci4pni/lFJp6cZb3TfVfTVE02EfaGklyc8PqD+mu89JH3H9tO2h5puZhILIuJQcf8VSQuabGYSLafx7qW3TDPeN/uunenPO8UFure7OiI+IOmjkj5VnK72pRh/DdZPY6dTmsa7VyaZZvynmtx37U5/3qkmwn5Q0qIJjy8plvWFiDhY3I5KelT9NxX14dMz6Ba3ow3381P9NI33ZNOMqw/2XZPTnzcR9q2SFtu+3PYMSZ+QtLGBPt7G9uziwolsz5Z0nfpvKuqNklYV91dJeqzBXn5Gv0zjXTbNuBred41Pfx4RPf+RtFzjV+RfkvRnTfRQ0tcVkv6n+NnVdG+SHtb4ad0JjV/bWC3pXZI2S9oj6V8lzeuj3h6UtEPSdo0Ha6Ch3q7W+Cn6dknbip/lTe+7ir56st94uyyQBBfogCQIO5AEYQeSIOxAEoQdSIKwA0kQdiCJ/we2QuT8VBKTHgAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "poisoned = pdata[np.all(plabels == targets, axis=1)]\n",
    "poisoned_labels = plabels[np.all(plabels == targets, axis=1)]\n",
    "print(len(poisoned))\n",
    "idx = 0\n",
    "plt.imshow(poisoned[idx].squeeze())\n",
    "print(f\"Label: {np.argmax(poisoned_labels[idx])}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 10000 samples\n",
      "Epoch 1/10\n",
      "10000/10000 [==============================] - 4s 390us/sample - loss: 0.6832 - accuracy: 0.7914\n",
      "Epoch 2/10\n",
      "10000/10000 [==============================] - 4s 393us/sample - loss: 0.2209 - accuracy: 0.9337\n",
      "Epoch 3/10\n",
      "10000/10000 [==============================] - 4s 393us/sample - loss: 0.1463 - accuracy: 0.9539\n",
      "Epoch 4/10\n",
      "10000/10000 [==============================] - 4s 400us/sample - loss: 0.1062 - accuracy: 0.9686\n",
      "Epoch 5/10\n",
      "10000/10000 [==============================] - 4s 431us/sample - loss: 0.0869 - accuracy: 0.9744\n",
      "Epoch 6/10\n",
      "10000/10000 [==============================] - 5s 472us/sample - loss: 0.0707 - accuracy: 0.9769\n",
      "Epoch 7/10\n",
      "10000/10000 [==============================] - 5s 453us/sample - loss: 0.0576 - accuracy: 0.9823\n",
      "Epoch 8/10\n",
      "10000/10000 [==============================] - 4s 435us/sample - loss: 0.0546 - accuracy: 0.9828\n",
      "Epoch 9/10\n",
      "10000/10000 [==============================] - 4s 425us/sample - loss: 0.0443 - accuracy: 0.9856\n",
      "Epoch 10/10\n",
      "10000/10000 [==============================] - 4s 421us/sample - loss: 0.0423 - accuracy: 0.9871\n"
     ]
    }
   ],
   "source": [
    "model.fit(pdata, plabels, nb_epochs=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The victim bank evaluates the model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Evaluation on clean test samples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Clean test set accuracy: 98.34%\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Prediction: 0\n"
     ]
    }
   ],
   "source": [
    "clean_preds = np.argmax(model.predict(x_test), axis=1)\n",
    "clean_correct = np.sum(clean_preds == np.argmax(y_test, axis=1))\n",
    "clean_total = y_test.shape[0]\n",
    "\n",
    "clean_acc = clean_correct / clean_total\n",
    "print(\"\\nClean test set accuracy: %.2f%%\" % (clean_acc * 100))\n",
    "\n",
    "# Display image, label, and prediction for a clean sample to show how the poisoned model classifies a clean sample\n",
    "\n",
    "c = 0 # class to display\n",
    "i = 0 # image of the class to display\n",
    "\n",
    "c_idx = np.where(np.argmax(y_test, 1) == c)[0][i] # index of the image in clean arrays\n",
    "\n",
    "plt.imshow(x_test[c_idx].squeeze())\n",
    "plt.show()\n",
    "clean_label = c\n",
    "print(\"Prediction: \" + str(clean_preds[c_idx]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Looks like an accurate model, except..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The attack was super effective!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Poison test set accuracy: 0.92%\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Prediction: 9\n"
     ]
    }
   ],
   "source": [
    "not_target = np.logical_not(np.all(y_test == targets, axis=1))\n",
    "px_test, py_test = backdoor.poison(x_test[not_target], y_test[not_target])\n",
    "poison_preds = np.argmax(model.predict(px_test), axis=1)\n",
    "poison_correct = np.sum(poison_preds == np.argmax(y_test[not_target], axis=1))\n",
    "poison_total = poison_preds.shape[0]\n",
    "\n",
    "poison_acc = poison_correct / poison_total\n",
    "print(\"\\nPoison test set accuracy: %.2f%%\" % (poison_acc * 100))\n",
    "\n",
    "c = 0 # index to display\n",
    "plt.imshow(px_test[c].squeeze())\n",
    "plt.show()\n",
    "clean_label = c\n",
    "print(\"Prediction: \" + str(poison_preds[c]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook displays a new poisoning attack that only needs to poison a small percent of a single class, but can still prove effective against any image at test time. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
